package com.junit.test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public abstract class ConccurentHarness {

    protected static final int CYCLES = 10000000;

    protected ExecutorService executor;

    @Before
    public void initExecutor() {
        executor = new ThreadPoolExecutor(4, 4, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CYCLES));
    }


    public void submitTasks() {
        for (int i = 0; i < CYCLES; i++) {
            executor.submit(newTask());
        }
    }

    public abstract Runnable newTask();

    @After
    public void collectResults() throws InterruptedException {
        waitAllTasks();
        checkResults();
    }

    public void waitAllTasks() throws InterruptedException {
        executor.shutdown();
        boolean terminated = executor.awaitTermination(5, TimeUnit.SECONDS);
        Assert.assertTrue("terminated", terminated);
        checkResults();
    }

    public abstract void checkResults();
}